home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / lib / Gen / inherits.sh < prev   
Encoding:
Linux/UNIX/POSIX Shell Script  |  1992-08-27  |  8.5 KB  |  378 lines

  1. #! /bin/sh
  2. # ----------------------------------------------------------------
  3. #   FILE
  4. #    inherits.sh
  5. #
  6. #   DESCRIPTION
  7. #       shell script which generates tags.h and inh.c
  8. #    and $TREE/$OD/lib/H/slots, which is used by Gen_creator.sh
  9. #    later on during the node function generation process.
  10. #
  11. #   NOTES
  12. #
  13. #   IDENTIFICATION
  14. #     $Header: /private/postgres/src/lib/Gen/RCS/inherits.sh,v 1.11 1991/04/28 09:16:09 cimarron Exp $
  15. # ----------------------------------------------------------------
  16. TMPDIR=${TMPDIR-/tmp}
  17. INHFILE=$TMPDIR/inh.$$
  18. TAGFILE=$TREE/$OD/lib/H/tags.h
  19. TAGTEMP=$TREE/$OD/lib/H/tags.temp
  20. SLOTFILE=$TREE/$OD/lib/H/slots
  21. OUTFILE=inh.c
  22.  
  23. # ----------------
  24. #     collect nodefiles
  25. # ----------------
  26. NODEFILES=''
  27. x=1
  28. numargs=$#
  29. while test $x -le $numargs ; do
  30.    NODEFILES="$NODEFILES $1"
  31.    x=`expr $x + 1`
  32.    shift
  33. done
  34.  
  35. # ----------------
  36. #     generate the initial inheritance graph
  37. # ----------------
  38. egrep -h '^class' $NODEFILES | \
  39. sed \
  40.  -e 's/^class (\([A-Za-z]*\))/\1/' \
  41.  -e 's/ public (\([A-Za-z]*\))/ \1/' \
  42.  -e 's/[ {}]*$//' > $INHFILE
  43.  
  44. # ----------------
  45. #    generate tags.h from the inheritance graph
  46. # ----------------
  47. cat > $TAGTEMP << 'EOF'
  48. /* ----------------------------------------------------------------
  49.  *   FILE
  50.  *    tags.h
  51.  *    
  52.  *   DESCRIPTION
  53.  *    node tag header file - generated by the inherits.sh
  54.  *    script from the contents of the nodes files.
  55.  *
  56.  *   NOTES
  57.  *
  58.  *   IDENTIFICATION
  59.  *    $Header: /private/postgres/src/lib/Gen/RCS/inherits.sh,v 1.11 1991/04/28 09:16:09 cimarron Exp $
  60.  * ----------------------------------------------------------------
  61.  */
  62.  
  63. EOF
  64. awk 'BEGIN { i = -1 }\
  65.      { printf("#define T_%s %d\n", $1, ++i) }' $INHFILE >> $TAGTEMP
  66.  
  67. # ----------------
  68. #     now extract slot names from node files and generate slots.temp
  69. # ----------------
  70. rm -f $SLOTFILE
  71. cat $NODEFILES | \
  72. egrep -v '(^#|^[     /]*\*|typedef|extern|Defs)'  | \
  73. sed -e 's/;//' \
  74.     -e '/\/\*/,/\*\//D' \
  75.     -e 's/    / /g' \
  76.     -e 's/  */ /g' \
  77.     -e 's/\\//' | \
  78. awk '
  79. # ----------------
  80. #    ORS and OFS are the output field and record separators
  81. #    nc is the number of "class"es we have scanned
  82. #    inside is a variable set to 1 when we are scanning the
  83. #       contents of a class definition.
  84. # ----------------
  85. BEGIN { 
  86.     ORS = " "; 
  87.     OFS = "";
  88.     nc = 0;
  89.     inside = 0;
  90. }
  91.  
  92. # ----------------
  93. #    first search for the "class" tag.  once found
  94. #    extract class information into the classes[] array.
  95. #    i is the slot number of the next slot we scan..
  96. # ----------------
  97. /class /,/{/     { 
  98.     class = substr($2,2,length($2)-2); 
  99.     classes[ nc++ ] = class;
  100.         i = 1;
  101.     inside = 1;
  102. }
  103.  
  104. # ----------------
  105. #    process the contents of the class definition
  106. #
  107. #    decl[ class 0 ] contains the number of slots + 1
  108. #    decl[ class x ] contains the slot name for slot x
  109. #    whole[ class x ] contains the entire declaration for slot x
  110. #    parents[ class ] contains the parent class names
  111. # ----------------
  112. /{/,/}/ {
  113.     if (inside == 0)
  114.         next;
  115.  
  116.         if ($1 ~ /{/)
  117.         next;
  118.  
  119.     if ($1 ~ /}/) {
  120.         decl[ class 0 ] = i;
  121.         i = 1;
  122.         inside = 0;
  123.         next;
  124.     }
  125.  
  126.     if ($1 ~ /inherits/) {
  127.         parent = substr($1,10,length($1)-10);
  128.         parents[ class ] = parent;
  129.  
  130.         if (parent != "Node") {
  131.             ndecs = decl[ parent 0 ];
  132.             for (j=1; j<ndecs; j++) {
  133.                   whole[ class i] = whole[ parent j ];
  134.                 decl[ class i++ ] = decl[ parent j ];
  135.             }
  136.         }
  137.         next;
  138.     }
  139.  
  140.     if ($1 ~ /struct/) {
  141.         whole[ class i ] = $0;
  142.            decl[ class i++ ] = substr($3,2,length($3)-1);
  143.         next;
  144.     }
  145.  
  146.     if ($1 !~ /inherits/ && $1 !~ /struct/ && $1 !~ /class/) {
  147.         whole[ class i ] = $0;
  148.         decl[ class i++ ] = $2;
  149.     }
  150. }
  151.  
  152. # ----------------
  153. #    all nodes have been scanned, now write node slot information.
  154. #    the output format is:
  155. #    
  156. #    {
  157. #    number-of-slots  class
  158. #    slot-name: slot-declaration
  159. #    slot-name: slot-declaration
  160. #       ...
  161. #    }
  162. #    
  163. #    example:
  164. #    
  165. #    {
  166. #    7 Plan
  167. #    cost:  Cost cost
  168. #    fragment:  Index fragment
  169. #    state:  struct EState *state
  170. #    qptargetlist:  List qptargetlist
  171. #    qpqual:  List qpqual
  172. #    lefttree:  struct Plan *lefttree
  173. #    righttree:  struct Plan *righttree
  174. #    }
  175. #
  176. # ----------------
  177. END {
  178.     decl[ class 0 ] = i;
  179.     
  180.     for (j=0; j<nc; j++) {
  181.         class = classes[ j ];
  182.         ndecs = decl[ class 0 ];
  183.         if (class != "Node") {
  184.             print "\n{";
  185.             print "\n" ndecs-1 " " class;
  186.             for (i=1; i<ndecs; i++) {
  187.                 print "\n" decl[ class i ] ":" \
  188.                            whole[ class i ];
  189.             }
  190.             print "\n}";
  191.             print "\n";
  192.         }
  193.     }
  194.     print "\n";
  195. }
  196. ' > $SLOTFILE
  197.  
  198. # ----------------
  199. #    now generate inh.c
  200. # ----------------
  201. cat > $OUTFILE << 'EOF'
  202. /* ----------------------------------------------------------------
  203.  *   FILE
  204.  *    inh.c
  205.  *    
  206.  *   DESCRIPTION
  207.  *    node inheritance graph file - generated by the inherits.sh
  208.  *    script from the contents of the nodes files.
  209.  *
  210.  *   NOTES
  211.  *    NodeIsType() now uses a lookup table instead of doing a
  212.  *    tree walk.  The first time you ask for a node's type, we
  213.  *    walk the tree and initialize the corresponding entries in
  214.  *    the table.  Subsequent calls go directly to the table.
  215.  *
  216.  *   IDENTIFICATION
  217.  *    $Header: /private/postgres/src/lib/Gen/RCS/inherits.sh,v 1.11 1991/04/28 09:16:09 cimarron Exp $
  218.  * ----------------------------------------------------------------
  219.  */
  220.  
  221. #include "tmp/c.h"
  222. #include "nodes/pg_lisp.h"
  223. #include "nodes/nodes.h"
  224. #include "nodes/primnodes.h"
  225. #include "nodes/execnodes.h"
  226. #include "nodes/relation.h"
  227. #include "nodes/plannodes.h"
  228. #include "nodes/mnodes.h"
  229. EOF
  230.  
  231. echo '#include' \"$TAGFILE\" >> $OUTFILE
  232. cat >> $OUTFILE << 'EOF'
  233.  
  234. struct nodeinfo {
  235.     char    *ni_name;
  236.     TypeId    ni_id;
  237.     TypeId    ni_parent;
  238.     Size    ni_size;
  239. };
  240. struct nodeinfo _NodeInfo[] = {
  241. EOF
  242.  
  243. awk '{ if ($2 == "") { $2 = "Node" };\
  244.        printf("    { \"%s\", T_%s, T_%s, sizeof(struct _%s) },\n", $1, $1, $2, $1) }' \
  245.       $INHFILE >> $OUTFILE
  246. cat >> $OUTFILE << 'EOF'
  247.     { "INVALID", 0, 0, 0 }
  248. };
  249.  
  250. #define _NClasses     (lengthof(_NodeInfo) - 1)
  251. #define _NClassBytes    ((_NClasses / 8) + 1)
  252.  
  253. TypeId _InvalidTypeId = (TypeId) _NClasses;
  254. bits8  _NodeClassArray[_NClasses][_NClassBytes];    
  255. bits8  _NodeBitMask[] = { 1<<0, 1<<1, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6, 1<<7 };
  256.  
  257. bool   _NodeInfoTrace = false;
  258.  
  259. /* ----------------
  260.  *    InitNodeArray initializes our node's inheritance table.
  261.  * ----------------
  262.  */
  263. void
  264. InitNodeArray(i)
  265.     register TypeId i;
  266. {
  267.     register TypeId j;
  268.     register int    q;
  269.     register int    r;
  270.  
  271.     /* ----------------
  272.      *    base clause for recursion: initializing the root node
  273.      * ----------------
  274.      */
  275.     if (i == T_Node) {
  276.     _NodeClassArray[i][0] = 1<<0;
  277.     return;
  278.     }
  279.  
  280.     /* ----------------
  281.      *    recursive initialization: initialize our parent, if necessary
  282.      * ----------------
  283.      */
  284.     j = _NodeInfo[i].ni_parent;
  285.     if (_NodeClassArray[j][0] == 0)
  286.     InitNodeArray(j);
  287.  
  288.     /* ----------------
  289.      *    now initialize ourself by copying our parent's bitmask and
  290.      *  setting our own bit.
  291.      * ----------------
  292.      */
  293.     for (q=0; q<_NClassBytes; q++)
  294.     _NodeClassArray[i][q] = _NodeClassArray[j][q];
  295.     
  296.     q = i / 8; r = i % 8;
  297.     _NodeClassArray[i][q] |= _NodeBitMask[r];
  298. }
  299.  
  300. /* ----------------
  301.  *    NodeIsType
  302.  *
  303.  *     determine if (thisNode) is of type (tag) or is a subclass
  304.  *    of type (tag).  We do this by consulting the master
  305.  *    node class array bitmap: look in the row corresponding
  306.  *    to (thisNode)'s type.  Now look at the bit in the position
  307.  *    indicated by (tag).  If this is set, then (thisNode) is
  308.  *    of type (tag), otherwise it's not.
  309.  *             
  310.  *    The table is initialized on demand.  If nobody ever asks
  311.  *    about a given class, then we never initialize that class's
  312.  *    information...
  313.  * ----------------
  314.  */
  315. bool
  316. NodeIsType(thisNode, tag)
  317.     Node        thisNode;
  318.     register TypeId     tag;
  319. {
  320.     register TypeId i;
  321.     register int    q;
  322.     register int    r;
  323.     
  324.     Assert(NodeIsValid(thisNode));
  325.     
  326.     i = NodeType(thisNode);
  327.     Assert(TypeIdIsValid(i));
  328.     Assert(TypeIdIsValid(tag));
  329.  
  330.     if (_NodeClassArray[i][0] == 0)
  331.     InitNodeArray(i);
  332.  
  333.     q = tag / 8; r = tag % 8;
  334.     return (bool)
  335.     (_NodeClassArray[i][q] & _NodeBitMask[r]);
  336. }
  337.     
  338. void
  339. Dump_NodeInfo()
  340. {
  341.     register TypeId    i;
  342.  
  343.     printf("%16.16s%16.16s%16.16s\n", 
  344.        "NODE NAME:", "NODE TAG:", "PARENT NODE:");
  345.  
  346.     for (i = 0; i < _InvalidTypeId; ++i)
  347.     printf("%16.16s%16.1d%16.16s\n",
  348.            _NodeInfo[i].ni_name,
  349.            _NodeInfo[i].ni_id, 
  350.            _NodeInfo[_NodeInfo[i].ni_parent].ni_name);
  351. }
  352.  
  353. EOF
  354. rm -f $INHFILE
  355.  
  356. # ----------------
  357. #    finally, compare the new tagfile with the old.
  358. #
  359. #    if the tagfile has changed, then it means that
  360. #    cinterface.a has to be remade because its tag #defines
  361. #    are different.
  362. # ----------------
  363. if [ -r $TAGFILE ]; then 
  364.     if cmp -s $TAGFILE $TAGTEMP ; then 
  365.         echo "tags.h unchanged";
  366.     else
  367.         mv $TAGTEMP $TAGFILE; 
  368.         echo "tags.h has changed; remake cinterface.a";
  369.     fi
  370. else
  371.     mv $TAGTEMP $TAGFILE;
  372. fi
  373.  
  374. # ----------------
  375. #    all done
  376. # ----------------
  377. exit 0
  378.